import org.junit.Test;
import sun.swing.StringUIClientPropertyKey;

import java.util.*;

/**
 * @description:
 * @author: duanjq
 * @time: 2021/8/29 21:07
 */
public class TestLambda {
    //原来的匿名内部类
    @Test
    public void test1(){
        Comparator<Integer>com=new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);//todo  其实就这一段代码有用
            }
        };
        TreeSet<Integer>ts=new TreeSet<>(com);

    }
    //Lambda表达式
    @Test
    public  void test2(){
        Comparator<Integer>com =(x,y)->Integer.compare(x,y);
        TreeSet<Integer>ts=new TreeSet<>(com);
    }

    List<Employee> employeeList= Arrays.asList(
     new Employee("张三",18,9999.99),
     new Employee("李四",38,5555.99),
     new Employee("王五",50,66666.66),
     new Employee("赵六",16,3333.33),
     new Employee("田七",8,7777.77)
    );
    //todo 需求：获取年龄大于35的员工信息，
    @Test
    public  void test3(){
        List<Employee>list=filterEmployees(employeeList);
        for(Employee employee:list){
            System.out.println(employee);
        }
    }

    // 获取年龄大于35的员工信息， 比较普通的做法
    public  List<Employee>filterEmployees(List<Employee>list){
        List<Employee>emps=new ArrayList<>();
        for(Employee emp:list){
            if(emp.getAge()>=35){
                emps.add(emp);
            }
        }
        return  emps;
    }

    // 获取工资大于5000的员工信息， 比较普通的做法
    public  List<Employee>filterEmployees2(List<Employee>list){
        List<Employee>emps=new ArrayList<>();
        for(Employee emp:list){
            if(emp.getSalary()>=5000){
                emps.add(emp);
            }
        }
        return  emps;
    }

    //todo ====================对上面操作可以进行如下优化=======================
    //todo 优化方式1 通过设计模式(策略),使用设计模式其实有用的代码就是比较那一段  这样如果新加其他比较方式得新加其他实现 比较麻烦
    @Test
    public void test4(){
        //获取年龄大于35
        List<Employee>list=filterEmployee(employeeList,new FilterEmployeeByAge());
        for(Employee employee:list){
            System.out.println(employee);
        }
        System.out.println("-----------------------------");
        //获取工资大于5000
        List<Employee>list1=filterEmployee(employeeList,new FilterEmployeeBySalary());
        for(Employee employee:list1){
            System.out.println(employee);
        }
    }


    public List<Employee>filterEmployee(List<Employee>list,MyPredicate<Employee>mp){
        List<Employee>emps=new ArrayList<>();
        for(Employee employee:list){
            if(mp.test(employee)){
                emps.add(employee);
            }
        }
        return  emps;
    }


    //todo 优化方式二:匿名内部类,参数使用匿名内部类 new MyPredicate<Employee>()，相当于直接实现MyPredicate接口,
    // 类似于传入FilterEmployeeBySalary、FilterEmployeeByAge 、其实有用的也是employee.getSalary()<=5000这段比较的代码
    //这样不同的比较匿名内部类不同实现就行了
    @Test
    public  void test5(){
        List<Employee>list=filterEmployee(employeeList, new MyPredicate<Employee>() {
            @Override
            public boolean test(Employee employee) {
                return employee.getSalary()<=5000;
            }
        });
        for(Employee employee:list){
            System.out.println(employee);
        }
    }
    //todo 优化方式三   Lambda表达式,直接传入需要比较的代码，也就是参数为一段代码,lambda是在在接口的基础山实现的，
    // 比如下面的(e)->e.getSalary()<=5000,是在 new MyPredicate接口上实现的
    @Test
    public  void test6(){
        List<Employee>list=filterEmployee(employeeList,(e)->e.getSalary()<=5000);
        list.forEach(System.out::println);
    }

    //todo 优化方式四，只用employeeList数据,stream api
    @Test
    public void test7(){
        employeeList.stream().filter((e)->e.getSalary()>=5000).forEach(System.out::println);
        System.out.println("===========把所有名字提取出来======================================");
        employeeList.stream().map(Employee::getName).forEach(System.out::println);

    }
}
